package com.kudian.restful.service;

import com.kudian.common.persistence.HibernateDao;
import com.kudian.common.service.BaseService;
import com.kudian.common.utils.NumberUtils;
import com.kudian.common.utils.PropertiesLoader;
import com.kudian.common.utils.StringUtils;
import com.kudian.restful.dao.*;
import com.kudian.restful.entity.Collection;
import com.kudian.restful.entity.GroupBuy;
import com.kudian.restful.entity.LoginSession;
import com.kudian.restful.entity.Seller;
import com.kudian.restful.vo.comment.CommentInfoVO;
import com.kudian.restful.vo.seller.*;
import com.spatial4j.core.context.SpatialContext;
import com.spatial4j.core.distance.DistanceUtils;
import com.spatial4j.core.shape.Rectangle;
import org.apache.log4j.Logger;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;

import java.sql.Timestamp;
import java.util.*;

/**
 * Created by Administrator on 2016/4/14.
 */
@Service
@Transactional(readOnly = true)
public class SellerService extends BaseService<Seller, Integer> {

    private static final Logger logger = Logger.getLogger(SellerService.class);

    @Autowired
    private SellerDao sellerDao;

    @Autowired
    private LoginSessionDao loginSessionDao;

    @Autowired
    private UsersDao usersDao;

    @Autowired
    private CollectionDao collectionDao;

    @Autowired
    private MediaResService mediaResService;

    @Autowired
    private CommentService commentService;

    @Autowired
    private OrderService orderService;

    @Autowired
    private GroupBuyDao groupBuyDao;

    @Override
    public HibernateDao<Seller, Integer> getEntityDao() {
        return sellerDao;
    }

    /**
     * 查找登录账号名下的商店
     * @param querySellerVO
     * @return
     */
    public List<Seller> query(QuerySellerVO querySellerVO) {
        String hql = "from Seller s where s.userId=:userId ";
        LoginSession entity = loginSessionDao.get(querySellerVO.getAccess_token());
        // UsersEntity u = usersDao.find(entity.getUserId());

        Map<String, Object> params = new HashMap<String, Object>();
        params.put("userId", entity.getUserId());
        return sellerDao.find(hql, params);
    }

    /**
     * 更新商户基础信息
     * @param vo
     */
    @Transactional(readOnly = false)
    public void update(UpdateSellerVO vo) {
        LoginSession entity = loginSessionDao.get(vo.getAccess_token());
        if (entity == null) {
            return;
        }

        // 只此一家
        Seller s = sellerDao.findUnique(Restrictions.eq("userId", entity.getUserId()));

        s.setTel(vo.getTel());
        s.setDeliveryTime(vo.getDeliveryTime());
        s.setMobilePhone(vo.getMobilePhone());
        s.setAddress(vo.getAddress());
        s.setMinChange(vo.getMinChange());
        s.setIsFirst(vo.getIsFirst());
        s.setFirstAmount(vo.getFirstAmount());
        s.setIsFullMinus(vo.getIsFullMinus());
        s.setFullAmount(vo.getFullAmount());
        s.setMinusAmount(vo.getMinusAmount());
        s.setIsShippingFree(vo.getIsShippingFree());
        s.setShippingFee(vo.getShippingFee());
        s.setIsHoliday(vo.getIsHoliday());
        s.setDiscount(vo.getDiscount());

        // 配送开始结束时间
        s.setDeliveryStart(vo.getDeliveryStart());
        s.setDeliveryEnd(vo.getDeliveryEnd());

        if (StringUtils.isBlank(vo.getLatitudes())) {
            s.setLatitudes(null);
        } else {
            s.setLatitudes(NumberUtils.toDouble(vo.getLatitudes()));
        }
        if (StringUtils.isBlank(vo.getLongitudes())) {
            s.setLongitudes(null);
        } else {
            s.setLongitudes(NumberUtils.toDouble(vo.getLongitudes()));
        }
        s.setModifyTime(new Timestamp(System.currentTimeMillis()));
        sellerDao.save(s);
    }

    /**
     * 更新商户基础信息
     * @param vo
     */
    @Transactional(readOnly = false)
    public void modify(ModifySellerVO vo) {
        LoginSession entity = loginSessionDao.get(vo.getAccess_token());
        if (entity == null) {
            return;
        }

        // 只此一家
        Seller s = sellerDao.findUnique(Restrictions.eq("userId", entity.getUserId()));

        s.setBusLicencePics(vo.getBusLicencePics());
        s.setCorporateIcardPics(vo.getCorporateIcardPics());
        s.setSellerPics(vo.getSellerPics());

        // 将标志位改为审核中 1
        s.setSellerStatus((short) 1);
        s.setModifyTime(new Timestamp(System.currentTimeMillis()));
        sellerDao.save(s);
    }

    @Transactional(readOnly = false)
    public void openseller(OpenVO vo) {
        LoginSession entity = loginSessionDao.get(vo.getAccess_token());
        if (entity == null) {
            return;
        }
        // 只此一家
        Seller s = sellerDao.findUnique(Restrictions.eq("userId", entity.getUserId()));

        s.setIsopen(true);
        sellerDao.save(s);
    }

    @Transactional(readOnly = false)
    public void closeseller(CloseVO vo) {
        LoginSession entity = loginSessionDao.get(vo.getAccess_token());
        if (entity == null) {
            return;
        }
        // 只此一家
        Seller s = sellerDao.findUnique(Restrictions.eq("userId", entity.getUserId()));

        s.setIsopen(false);
        sellerDao.save(s);
    }

    public Rectangle getRect(String latitudes, String longitudes) {
        // 移动设备经纬度
        double lon = NumberUtils.toDouble(longitudes);
        double lat = NumberUtils.toDouble(latitudes);

        PropertiesLoader loader = new PropertiesLoader("env.properties");
        // 千米
        int radius = loader.getInteger("DIS_RANGE");
        SpatialContext geo = SpatialContext.GEO;
        Rectangle rectangle = geo.getDistCalc().calcBoxByDistFromPt(
                geo.makePoint(lon, lat), radius * DistanceUtils.KM_TO_DEG, geo, null);
        // System.out.println(rectangle.getMinX() + "-" + rectangle.getMaxX());// 经度范围
        // System.out.println(rectangle.getMinY() + "-" + rectangle.getMaxY());// 纬度范围
        return rectangle;
    }

    /**
     * 求两点之间的距离
     * @param latitudes
     * @param longitudes
     * @param latitudes1
     * @param longitudes1
     * @return
     */
    public int getDis(double latitudes, double longitudes, double latitudes1, double longitudes1) {
        SpatialContext geo = SpatialContext.GEO;
        double distance = geo.calcDistance(geo.makePoint(longitudes, latitudes),
                geo.makePoint(longitudes1, latitudes1)) * DistanceUtils.DEG_TO_KM;
        return (int) (distance * 1000);
    }

    public List<ClientSellerItemVO> queryByClient(ClientSellerVO vo) {
        List<ClientSellerItemVO> ret = new ArrayList<ClientSellerItemVO>();

        if (StringUtils.isBlank(vo.getLongitudes()) || StringUtils.isBlank(vo.getLatitudes())) {
            return new ArrayList<ClientSellerItemVO>();
        }

        Rectangle rect = getRect(vo.getLatitudes(), vo.getLongitudes());
        // 范围5公里店铺
        List<Seller> ls = sellerDao.find(
                Restrictions.eq("gtId", vo.getGtId()), Restrictions.eq("sellerStatus", (short)2),
                Restrictions.between("latitudes", rect.getMinY(), rect.getMaxY()),
                Restrictions.between("longitudes", rect.getMinX(), rect.getMaxX()));

        for (Seller s : ls) {
            if (ret == null)
                ret = new ArrayList<ClientSellerItemVO>();

            ClientSellerItemVO item = new ClientSellerItemVO();
            item.setSellerId(s.getSellerId());
            item.setName(s.getName());

            CommentInfoVO cinfo = commentService.queryBySeller(s.getSellerId());
            if (cinfo != null) {
                // 取平均值
                item.setCommentRank(cinfo.getCommentRank());
                // 评论数
                item.setCommentCount(cinfo.getCommentCount());
            } else {
                // 取平均值
                item.setCommentRank((short)0);
                // 评论数
                item.setCommentCount(0);
            }
            // 取月销量
            item.setSales(orderService.getOrdersNumBySeller(s.getSellerId()));
            // item.setDistance("0");
            int dis = getDis(NumberUtils.toDouble(vo.getLatitudes()), NumberUtils.toDouble(vo.getLongitudes())
                ,s.getLatitudes(), s.getLongitudes());
            item.setDistance(dis + "米");
            item.setDis(dis);
            item.setMinChange(s.getMinChange());

            item.setIsFirst(s.getIsFirst());
            item.setFirstAmount(s.getFirstAmount());
            item.setIsFullMinus(s.getIsFullMinus());
            item.setFullAmount(s.getFullAmount());
            item.setMinusAmount(s.getMinusAmount());
            item.setIsShippingFree(s.getIsShippingFree());
            item.setShippingFee(s.getShippingFee());
            item.setIsopen(s.getIsopen() == null ? false : s.getIsopen());
            String pic = s.getSellerPics();
            if (StringUtils.isNotBlank(pic)) {
                String[] pics = pic.split(",");
                pic = pics[0];
                item.setPic(mediaResService.getResUrl(pic));
            }
            ret.add(item);
        }
        ClientSellerComparator comparator = new ClientSellerComparator();
        Collections.sort(ret, comparator);
        return ret;
    }

    /**
     * 客户端取得某一店铺信息
     * @param vo
     * @return
     */
    public DetailsSellerItemRetVO detailsByClient(DetailsSellerVO vo) {
        DetailsSellerItemRetVO o = new DetailsSellerItemRetVO();
        Seller s = this.sellerDao.get(vo.getSellerId());
        if (s == null) {
            return null;
        }
        o.setSellerId(s.getSellerId());
        o.setName(s.getName());
        o.setTel(s.getTel());
        o.setDeliveryStart(s.getDeliveryStart());
        o.setDeliveryEnd(s.getDeliveryEnd());
        o.setAddress(s.getAddress());
        o.setSellerPics(this.mediaResService.getResUrls(s.getSellerPics()));
        o.setIsopen(s.getIsopen());

        CommentInfoVO cinfo = commentService.queryBySeller(s.getSellerId());
        if (cinfo != null) {
            // 取平均值
            o.setCommentRank(cinfo.getCommentRank());
            // 评论数
            o.setCommentCount(cinfo.getCommentCount());
        } else {
            // 取平均值
            o.setCommentRank((short)0);
            // 评论数
            o.setCommentCount(0);
        }
        o.setIsFirst(s.getIsFirst());
        o.setFirstAmount(s.getFirstAmount());
        o.setIsFullMinus(s.getIsFullMinus());
        o.setFullAmount(s.getFullAmount());
        o.setMinusAmount(s.getMinusAmount());
        o.setIsShippingFree(s.getIsShippingFree());
        o.setShippingFee(s.getShippingFee());
        o.setMinChange(s.getMinChange());
        // 取月销量
        o.setSales(orderService.getOrdersNumBySeller(s.getSellerId()));

        if (StringUtils.isBlank(vo.getLatitudes()) || StringUtils.isBlank(vo.getLongitudes())) {
            o.setDistance("");
        } else {
            int dis = getDis(NumberUtils.toDouble(vo.getLatitudes()), NumberUtils.toDouble(vo.getLongitudes())
                    , s.getLatitudes(), s.getLongitudes());
            o.setDistance(dis + "米");
        }
        o.setIsopen(s.getIsopen());

        if (StringUtils.isBlank(vo.getAccess_token())) {
            o.setIsCollect(false);
            o.setCollectionId(0);
            return o;
        }
        LoginSession ent = loginSessionDao.get(vo.getAccess_token());
        if (ent == null) {
            o.setIsCollect(false);
            o.setCollectionId(0);
            return o;
        }

        List<Collection> cs = collectionDao.find(Restrictions.eq("userId", ent.getUserId()),
                Restrictions.eq("sellerId", vo.getSellerId()), Restrictions.eq("goodsId", 0));
        // 是否收藏
        if (cs == null || cs.isEmpty()) {
            o.setIsCollect(false);
            o.setCollectionId(0);
        } else {
            o.setIsCollect(true);
            o.setCollectionId(cs.get(0).getCollectionId());
        }
        return o;
    }

    public List<QueryGroupBuyItemVO> getGroupBuy(QueryGroupBuyVO vo) {
        List<QueryGroupBuyItemVO> ret = new ArrayList<QueryGroupBuyItemVO>();
        List<GroupBuy> ls = groupBuyDao.find(Restrictions.eq("sellerId", vo.getSellerId()));
        if (ls == null || ls.isEmpty()) {
            return ret;
        }
        for (GroupBuy gb : ls) {
            QueryGroupBuyItemVO item = new QueryGroupBuyItemVO();
            item.setGbTypeId(gb.getGbTypeId());
            item.setName(gb.getName());
            item.setBookingTm(gb.getBookingTm());
            item.setDeliveryTm(gb.getDeliveryTm());
            ret.add(item);
        }

        return ret;
    }
}
